package video

import (
	"fmt"
	"gitee.com/mootok/mootok/src/constant/strings"
	"gitee.com/mootok/mootok/src/models"
	"gitee.com/mootok/mootok/src/services/video"
	"gitee.com/mootok/mootok/src/storage/database"
	"gitee.com/mootok/mootok/src/storage/es"
	"gitee.com/mootok/mootok/src/utils/logging"
	"gitee.com/mootok/mootok/src/web/api"
	"gitee.com/mootok/mootok/src/web/common/response"
	"github.com/gin-gonic/gin"
	"github.com/sirupsen/logrus"
	"net/http"
)

var Service video.Service

func (i *ApiVideoImpl) SearchVideos(c *gin.Context, query string, params api.SearchVideosParams) {
	var err error
	var after = ""

	logger := logging.LogService("Video.Search").WithFields(logrus.Fields{
		"query": query,
	})

	if params.Cursor != nil {
		logger = logger.WithField("cursor", *params.Cursor)
		after = *params.Cursor
	} else {
		logger = logger.WithField("cursor", "")
		after = ""
	}

	results, err := es.VideoStore.Search(query, after)

	if err != nil {
		logger.Errorf("retrieve search result failed:%v", err)
		response.FailWithMsg(c, http.StatusInternalServerError, strings.EsSearchFailedError, strings.InternalServiceError)
		return
	}

	if len(results.Hits) == 0 {
		response.SuccessWithDetail(c, strings.SuccessCode, strings.Success, &api.VideoCursoredListResp{
			NextCursor: "",
			Items:      []api.VideoInfo{},
		})
		logger.Info("search success with empty result")
		return
	}

	videos := make([]models.Video, len(results.Hits))
	videoIds := make([]int, len(results.Hits))

	for i, hit := range results.Hits {
		videoIds[i] = hit.ID
	}

	if err = database.Client.Where("id IN ?", videoIds).Find(&videos).Error; err != nil {
		logger.Errorf("retrieve search result failed:%v", err)
		response.FailWithMsg(c, http.StatusInternalServerError, strings.DataBaseSelectErrorCode, strings.InternalServiceError)
		return
	}

	videoInfos := make([]api.VideoInfo, len(videos))

	userIdAny, _ := c.Get(strings.UserLoginContext)
	userId := userIdAny.(int)

	if err := Service.ToVideoInfo(videos, &userId, &videoInfos); err != nil {
		logger.Errorf("retrieve video info failed:%v", err)
		response.FailWithMsg(c, http.StatusInternalServerError, strings.DataBaseSelectErrorCode, strings.InternalServiceError)
		return
	}

	sorts := results.Hits[len(results.Hits)-1].Sort
	cursor := fmt.Sprintf("%f,%f", sorts[0], sorts[1])
	response.SuccessWithDetail(c, strings.SuccessCode, strings.Success, &api.VideoCursoredListResp{
		NextCursor: cursor,
		Items:      videoInfos,
	})
	logger.Infof("search success.%v", results.Hits)
}
